/**
 * JSparrow - Une version numérique du jeu "Attention Pirates !" - Copyright (C) 2014 Black Pearl
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 */
package App.Modele;

import java.awt.Point;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;

/**
 * Classe de gestion de bateau.
 *
 * @author BlackPearl
 */
public class Bateau extends EntiteCase implements Serializable {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Point emplacement;
    public final int idJoueur;

    /**
     * Default Constructor
     * DO NOT REMOVE NOR EDIT !!
     */
    public Bateau()
    {
    	idJoueur = 0;
    }
    /**
     * Initalisation du contexte.
     *
     * @param id ID du bateau
     */
    public Bateau(int id) {
        /**
         * @todo Modifier l'appel à la classe parente (le joueur choisit pirates et canons au début)
         * @todo Finir l'initialisation du tableau des pièces
         */
        super(0, 1, 0);
        this.emplacement = new Point(0, 0);
        this.idJoueur = id;
        //System.out.println(this.getDeplacementsPossibles()); // DEBUG
    }

    /**
     * Obtenir la liste des déplacements possibles du bateau.
     *
     * @return liste de coordonnées (ne peut jamais etre vide)
     */
    public ArrayList<Point> getDeplacementsPossibles() {
    	HashSet<Point> result = new HashSet<Point>();
    	if(Configuration.EmplacementsPort.contains(this.emplacement))
    	{
    		for (Point p : Configuration.EmplacementsPort) {
				result.addAll(calculDeplacementRecursif(p, (this.nbPirates == 0 ? 1 : this.nbPirates)));
			}
    		result.remove(this.emplacement);
    	}else{
    		result.addAll(calculDeplacementRecursif(this.emplacement, (this.nbPirates == 0 ? 1 : this.nbPirates)));
    	}
    	
    	return new ArrayList<Point>(result);
    }

    /**
     * Calculer la liste des déplacements possibles du bateau.
     *
     * @param point Point de départ
     * @param nbRestant Nombre de déplacements restants
     * @return liste de coordonnées (peut être vide)
     */
    private ArrayList<Point> calculDeplacementRecursif(Point point, int nbRestant) {
        HashSet<Point> result = new HashSet<Point>();

        if (nbRestant > 0) {
            HashSet<Point> deplacementsBase = new HashSet<Point>();
            HashSet<Point> deplacementsBaseSorted = new HashSet<Point>();
            deplacementsBase.add(new Point(-1 + point.x, -1 + point.y));
            deplacementsBase.add(new Point(-1 + point.x, +1 + point.y));
            deplacementsBase.add(new Point(0 + point.x, -2 + point.y));
            deplacementsBase.add(new Point(0 + point.x, +2 + point.y));
            deplacementsBase.add(new Point(+1 + point.x, -1 + point.y));
            deplacementsBase.add(new Point(+1 + point.x, +1 + point.y));
            for (Point p : deplacementsBase) {
				//if(p.x >= 0 && p.y >= 0 && p.x < 9 && p.y < 10)
					deplacementsBaseSorted.add(p);
			}
            result.addAll(deplacementsBaseSorted);

            for (Point p : deplacementsBaseSorted) {
                result.addAll(calculDeplacementRecursif(p, nbRestant - 1));
            }
        }
        return new ArrayList<Point>(result);
    }

    /**
     * Obtenir l'emplacement du bateau.
     *
     * @return coordonnées du bateau
     */
    public Point getEmplacement() {
        return this.emplacement;
    }

    /**
     * Réparer le bateau.
     *
     * @param arrayPiece liste des pièces
     */
    public void reparer(TypePiece[] arrayPiece) {
        this.arrayPiece = arrayPiece;
    }

    /**
     * Prendre un trésor à bord du bateau.
     *
     * @param nbNouveauxTresor le nombre de trésors que le joueur récupère après un combat
     * @return -1 si l'emplacement 6 est occupé sinon le nombre de trésors en trop (cas qui arrive
     * quand le bateau dépasse les 6 trésors)
     */
    public int prendreTresor(int nbNouveauxTresor) {
        //if (arrayPiece[5] != TypePiece.Tresor) {
        //    return -1;
        //}
        int totalTresor = this.nbTresors + nbNouveauxTresor;
        if (totalTresor > 6) {
            super.nbTresors = 6;
            return (totalTresor - 6);
        } else {
            super.nbTresors = totalTresor;
        }
        arrayPiece[5]=TypePiece.Tresor;
        return 0;
    }

    public int getNbTresors() {
		return super.nbTresors;
	}
    /**
     * Déplacer le bateau.
     *
     * @param point nouvelles coordonnées du bateau
     */
    public void deplacer(Point point) {
        this.emplacement = point;
    }

    /**
     * Obtenir l'ID du joueur associé au bateau.
     *
     * @return ID du joueur
     */
    public int getIdJoueur() {
        return idJoueur;
    }

    @Override
    public String toString() {
        StringBuilder bateauStringBuffer = new StringBuilder();
        int num;
        for (int i = 0; i < arrayPiece.length; i++) {
            num = i + 1;
            if (arrayPiece[i] == TypePiece.Pirate) {
                bateauStringBuffer.append("Piece n°" + num + ": Pirate; ");
            } else if (arrayPiece[i] == TypePiece.Canon) {
                bateauStringBuffer.append("Piece n°" + num + ": Canon; ");
            } else if (arrayPiece[i] == TypePiece.Tresor) {
                bateauStringBuffer.append("Piece n°" + num + ": Tresor; ");
            } else if (arrayPiece[i] == TypePiece.Vide) {
                bateauStringBuffer.append("Piece n°" + num + ": Vide; ");
            } else {
                bateauStringBuffer.append("Piece n°" + num + ": Vide; ");
            }
        }
        bateauStringBuffer.append("nbTresors: " + this.getNbTresors() + "; ");
        bateauStringBuffer.append("nbPirates:" + this.getNbPirates() + "; ");
        bateauStringBuffer.append("nbCanons: " + this.getNbCanons() + "; ");
        return bateauStringBuffer.toString();
    }
    
    public String toCom(){
    	StringBuilder bateauStringBuffer = new StringBuilder();
        int num;
        for (int i = 0; i < arrayPiece.length; i++) {
            num = i + 1;
            if (arrayPiece[i] == TypePiece.Pirate) {
                bateauStringBuffer.append("1");
            } else if (arrayPiece[i] == TypePiece.Canon) {
                bateauStringBuffer.append("2");
            } else if (arrayPiece[i] == TypePiece.Tresor) {
                bateauStringBuffer.append("3");
            } else if (arrayPiece[i] == TypePiece.Vide) {
                bateauStringBuffer.append("0");
            } else {
                bateauStringBuffer.append("0");
            }
            if(num < arrayPiece.length){
            	bateauStringBuffer.append("-");
            }
        }
        bateauStringBuffer.append("_");
        bateauStringBuffer.append( this.getNbTresors());
        bateauStringBuffer.append("_");
        bateauStringBuffer.append( this.getIdJoueur());
        return bateauStringBuffer.toString();
    }
}
